﻿using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;
using TMPro;

/// <summary>
/// UI管理系统 - 负责显示生命值和心跳信息的用户界面
/// 支持PC和VR模式的不同UI显示方式，包括手部跟随、头部跟随等功能
/// </summary>
public class UI : UdonSharpBehaviour
{
    // ================================ 画布引用设置 ================================
    [Header("画布引用")]
    [Tooltip("PC端画布 - 推荐设置为Screen Space Overlay模式；如需在世界中跟随玩家，请设为World Space")]
    public Canvas pcCanvas;
    
    [Tooltip("VR端画布 - 必须设置为World Space模式，脚本将自动处理手部或头部跟随")]
    public Canvas vrCanvas;

    // ================================ 数据源设置 ================================
    [Header("数据源")]
    [Tooltip("生命值系统引用 - 将场景中的WorldHealth组件拖拽到此处，用于获取生命值和心跳数据")]
    public WorldHealth worldHealth;

    // ================================ 文本组件引用 ================================
    [Header("PC端文本组件")]
    [Tooltip("PC端生命值显示文本 - 使用TextMeshPro UGUI组件显示生命值信息")]
    public TextMeshProUGUI pcHealthText;
    
    [Tooltip("PC端心跳显示文本 - 使用TextMeshPro UGUI组件显示心跳信息")]
    public TextMeshProUGUI pcHeartRateText;

    [Header("VR端文本组件")]
    [Tooltip("VR端生命值显示文本 - 使用TextMeshPro UGUI组件显示生命值信息")]
    public TextMeshProUGUI vrHealthText;
    
    [Tooltip("VR端心跳显示文本 - 使用TextMeshPro UGUI组件显示心跳信息")]
    public TextMeshProUGUI vrHeartRateText;

    // ================================ VR手部UI设置 ================================
    [Header("VR手部UI参数")]
    [Tooltip("手部UI显示模式 - 0:手腕位置 1:手掌前方 2:手指前端，不同模式下UI的相对位置不同")]
    [Range(0, 2)] public int vrHandUIMode = 0;
    
    [Tooltip("UI与手部的基础距离 - UI显示位置距离手部的基本距离（米）")]
    [Range(0.1f, 0.5f)] public float vrHandUIDistance = 0.2f;
    
    [Tooltip("UI前后偏移量 - 相对于手部朝向的前后偏移，正值向前，负值向后（米）")]
    [Range(-0.2f, 0.2f)] public float vrHandUIFrontOffset = 0.1f;
    
    [Tooltip("UI上下偏移量 - 相对于手部的垂直偏移，正值向上，负值向下（米）")]
    [Range(-0.2f, 0.2f)] public float vrHandUIHeightOffset = 0.05f;
    
    [Tooltip("手部跟随平滑度 - 控制UI跟随手部移动的平滑程度，数值越大越平滑")]
    [Range(1f, 20f)] public float handUIFollowSmoothness = 10f;
    
    [Tooltip("跟随速度倍数 - 全局跟随速度的倍数，提高此值可以加快UI响应速度")]
    [Range(0.5f, 5f)] public float followSpeedMultiplier = 2f;

    // ================================ VR回退模式设置 ================================
    [Header("VR回退距离")]
    [Tooltip("距离调节滑条 - 当无法检测到手部时，UI回退到头部前方的距离调节（0-1映射到最小-最大距离）")]
    [Range(0f, 1f)] public float vrUIDistanceSlider = 0.5f;
    
    [Tooltip("回退最小距离 - UI回退到头部前方时的最近距离（米）")]
    [Range(0.5f, 2f)] public float vrUIMinDistance = 1f;
    
    [Tooltip("回退最大距离 - UI回退到头部前方时的最远距离（米）")]
    [Range(2f, 5f)] public float vrUIMaxDistance = 3f;

    // ================================ 内部状态变量 ================================
    private bool isVRMode; // 当前是否为VR模式
    private VRCPlayerApi.TrackingData leftHand; // 左手追踪数据
    private VRCPlayerApi.TrackingData rightHand; // 右手追踪数据
    private float lastUIUpdateTime = 0f; // 上次UI更新时间
    
    // ================================ UI刷新设置 ================================
    [Header("UI刷新设置")]
    [Tooltip("UI文本更新频率 - 控制生命值和心跳文本的更新间隔，降低此值可提高响应速度但增加性能开销")]
    [Range(0.05f, 1f)] public float uiUpdateInterval = 0.25f;

    // ================================ PC端跟随设置 ================================
    [Header("PC端跟随设置")]
    [Tooltip("PC画布跟随距离 - 仅当PC画布设置为World Space时生效，控制画布与玩家的水平距离")]
    [Range(0.5f, 5f)] public float pcFollowDistance = 1.2f;
    
    [Tooltip("PC画布高度偏移 - 仅当PC画布设置为World Space时生效，控制画布相对玩家的垂直偏移")]
    [Range(-1f, 1f)] public float pcHeightOffset = 0.2f;

    /// <summary>
    /// 初始化UI系统 - 启用画布并进行首次文本更新
    /// </summary>
    void Start()
    {
        if (pcCanvas != null) pcCanvas.enabled = true; // 启用PC画布
        if (vrCanvas != null) vrCanvas.enabled = true; // 启用VR画布
        UpdateHUDTexts(); // 进行首次文本更新
    }

    /// <summary>
    /// 每帧更新 - 处理UI文本更新和画布位置跟随
    /// </summary>
    void Update()
    {
        // 低频刷新文本（不依赖 LocalPlayer）
        if (Time.time - lastUIUpdateTime >= uiUpdateInterval)
        {
            lastUIUpdateTime = Time.time;
            UpdateHUDTexts();
        }

        if (Networking.LocalPlayer == null)
        {
            return;
        }

        isVRMode = Networking.LocalPlayer.IsUserInVR();

        // PC 画布始终启用（若有）
        if (pcCanvas != null && !pcCanvas.enabled)
        {
            pcCanvas.enabled = true;
        }

        // VR 画布：VR时手部跟随；非VR时回退到头部/玩家前方
        if (vrCanvas != null)
        {
            if (isVRMode)
            {
                UpdateVRHandUITracking();
            }
            else
            {
                PositionVRCanvasScreenFront();
            }
        }

        // PC 画布：若为World Space，可在场景中跟随玩家前方（Overlay下此变换无可见效果）
        if (!isVRMode && pcCanvas != null)
        {
            PositionPCCanvasScreenFront();
        }

    }

    /// <summary>
    /// 更新HUD文本显示 - 从WorldHealth获取数据并更新所有文本组件
    /// </summary>
    void UpdateHUDTexts()
    {
        if (worldHealth == null) return;

        int health = worldHealth.GetCurrentHealth();
        int maxHealth = worldHealth.GetMaxHealth();
        int heart = worldHealth.currentHeartRate; // public 字段

        string healthStr = "♥ 生命: " + health + "/" + maxHealth;
        string heartStr = "💗 心跳: " + heart + " /m";

        // 颜色：健康>60%绿，>30%橙，否则红
        float hpPct = maxHealth > 0 ? (float)health / maxHealth : 0f;
        Color hpColor = hpPct > 0.6f ? new Color(0f, 1f, 0f, 1f) : (hpPct > 0.3f ? new Color(1f, 0.8f, 0f, 1f) : new Color(1f, 0f, 0f, 1f));

        // 根据心跳值设置颜色：<60蓝色，<=100绿色，<=140橙色，>140红色
        Color hrColor = heart < 60 ? Color.blue : (heart <= 100 ? Color.green : (heart <= 140 ? new Color(1f, 0.8f, 0f, 1f) : Color.red));
        if (pcHealthText != null)
        {
            pcHealthText.text = healthStr;
            pcHealthText.color = hpColor;
            pcHealthText.enabled = true;
        }
        if (pcHeartRateText != null)
        {
            pcHeartRateText.text = heartStr;
            pcHeartRateText.color = hrColor;
            pcHeartRateText.enabled = true;
        }
        if (vrHealthText != null)
        {
            vrHealthText.text = healthStr;
            vrHealthText.color = hpColor;
            vrHealthText.enabled = true;
        }
        if (vrHeartRateText != null)
        {
            vrHeartRateText.text = heartStr;
            vrHeartRateText.color = hrColor;
            vrHeartRateText.enabled = true;
        }
    }

    /// <summary>
    /// 更新VR手部UI追踪 - 让VR画布跟随玩家的手部移动
    /// </summary>
    void UpdateVRHandUITracking()
    {
        if (vrCanvas == null) return;

        leftHand = Networking.LocalPlayer.GetTrackingData(VRCPlayerApi.TrackingDataType.LeftHand);
        rightHand = Networking.LocalPlayer.GetTrackingData(VRCPlayerApi.TrackingDataType.RightHand);
        bool useRight = rightHand.position != Vector3.zero;
        var hand = useRight ? rightHand : leftHand;

        if (hand.position != Vector3.zero)
        {
            Vector3 targetPos = CalculateHandUIPosition(hand);
            Quaternion targetRot = CalculateHandUIRotation(hand);
            // 通过倍数提升 t，数值越大越快；Clamp01 防止过冲
            float t = Mathf.Clamp01(handUIFollowSmoothness * followSpeedMultiplier * Time.deltaTime);
            vrCanvas.transform.position = Vector3.Lerp(vrCanvas.transform.position, targetPos, t);
            vrCanvas.transform.rotation = Quaternion.Slerp(vrCanvas.transform.rotation, targetRot, t);
        }
        else
        {
            PositionVRCanvasScreenFront();
        }
    }

    /// <summary>
    /// 计算手部UI位置 - 根据手部追踪数据和设置计算UI应该显示的位置
    /// </summary>
    Vector3 CalculateHandUIPosition(VRCPlayerApi.TrackingData hand)
    {
        Vector3 forward = hand.rotation * Vector3.forward;
        Vector3 up = hand.rotation * Vector3.up;
        float dist = vrHandUIDistance;
        Vector3 offset = Vector3.zero;

        switch (vrHandUIMode)
        {
            case 0: // 手腕
                offset = forward * vrHandUIFrontOffset + up * vrHandUIHeightOffset;
                break;
            case 1: // 手掌
                offset = forward * (dist + vrHandUIFrontOffset) + up * vrHandUIHeightOffset;
                break;
            case 2: // 手指
                offset = forward * (dist * 1.5f + vrHandUIFrontOffset) + up * (vrHandUIHeightOffset + 0.05f);
                break;
        }

        return hand.position + offset;
    }

    /// <summary>
    /// 计算手部UI旋转 - 让UI始终面向玩家
    /// </summary>
    Quaternion CalculateHandUIRotation(VRCPlayerApi.TrackingData hand)
    {
        Vector3 forward = hand.rotation * Vector3.forward;
        Vector3 up = hand.rotation * Vector3.up;
        return Quaternion.LookRotation(-forward, up);
    }

    /// <summary>
    /// 将VR画布定位到屏幕前方 - 当无法检测到手部时的回退模式
    /// </summary>
    void PositionVRCanvasScreenFront()
    {
        if (vrCanvas == null || Networking.LocalPlayer == null) return;

        var head = Networking.LocalPlayer.GetTrackingData(VRCPlayerApi.TrackingDataType.Head);
        if (head.position != Vector3.zero)
        {
            PositionVRCanvasAtHead(head);
        }
        else
        {
            PositionVRCanvasAtPlayer();
        }
    }

    void PositionVRCanvasAtHead(VRCPlayerApi.TrackingData head)
    {
        float dist = Mathf.Lerp(vrUIMinDistance, vrUIMaxDistance, vrUIDistanceSlider);
        Vector3 forward = head.rotation * Vector3.forward;
        Vector3 up = head.rotation * Vector3.up;
        Vector3 targetPos = head.position + forward * dist + up * vrHandUIHeightOffset;
        Quaternion targetRot = Quaternion.LookRotation((head.position - targetPos).normalized);
        float t = Mathf.Clamp01(handUIFollowSmoothness * followSpeedMultiplier * Time.deltaTime);
        vrCanvas.transform.position = Vector3.Lerp(vrCanvas.transform.position, targetPos, t);
        vrCanvas.transform.rotation = Quaternion.Slerp(vrCanvas.transform.rotation, targetRot, t);
    }

    void PositionVRCanvasAtPlayer()
    {
        Vector3 playerPos = Networking.LocalPlayer.GetPosition();
        Vector3 viewDir = Networking.LocalPlayer.GetRotation() * Vector3.forward;
        float dist = Mathf.Lerp(vrUIMinDistance, vrUIMaxDistance, vrUIDistanceSlider);
        Vector3 targetPos = playerPos + viewDir * dist + Vector3.up * vrHandUIHeightOffset;
        Quaternion targetRot = Quaternion.LookRotation((playerPos - targetPos).normalized);
        float t = Mathf.Clamp01(handUIFollowSmoothness * followSpeedMultiplier * Time.deltaTime);
        vrCanvas.transform.position = Vector3.Lerp(vrCanvas.transform.position, targetPos, t);
        vrCanvas.transform.rotation = Quaternion.Slerp(vrCanvas.transform.rotation, targetRot, t);
    }

    // PC World Space 画布在玩家前方定位（如果是Overlay，此变换对显示无影响）
    /// <summary>
    /// 定位PC画布到玩家前方 - 仅当PC画布为World Space模式时生效
    /// </summary>
    void PositionPCCanvasScreenFront()
    {
        if (Networking.LocalPlayer == null || pcCanvas == null) return;
        Vector3 playerPos = Networking.LocalPlayer.GetPosition();
        Vector3 viewDir = Networking.LocalPlayer.GetRotation() * Vector3.forward;
        Vector3 targetPos = playerPos + viewDir * pcFollowDistance + Vector3.up * pcHeightOffset;
        Quaternion targetRot = Quaternion.LookRotation((playerPos - targetPos).normalized);
        float t = Mathf.Clamp01(handUIFollowSmoothness * followSpeedMultiplier * Time.deltaTime);
        pcCanvas.transform.position = Vector3.Lerp(pcCanvas.transform.position, targetPos, t);
        pcCanvas.transform.rotation = Quaternion.Slerp(pcCanvas.transform.rotation, targetRot, t);
    }
}
